﻿using AppMachine.Controls.ValidationRules;
using AppMachine.Domain.LogicCom.AppComs;
using AppMachine.EntityFrameworkCore.Repositories.LogicCom;
using AppMachine.EntityFrameworkCore.Repositories.PerpDev;
using PerpheralDevice;
using PerpheralDevice.Units;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace AppMachine.Controls.Primitive {
    public class PrimAxis : Prim {
        static PrimAxis() {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(PrimAxis), new FrameworkPropertyMetadata(typeof(PrimAxis)));
        }

        public override void OnApplyTemplate() {

            base.OnApplyTemplate();

            if (this.GetTemplateChild("xNameButtonMovePos") is Button tempBtnMovePos) {
                tempBtnMovePos.PreviewMouseLeftButtonDown += (sender, evt) => {
                    this.mfComMotor?.DoMoving();
                };
                tempBtnMovePos.PreviewMouseLeftButtonUp += (sender, evt) => {
                    this.mfComMotor?.Stop();
                };
            }

            if (this.GetTemplateChild("xNameButtonMoveNeg") is Button tempBtnMoveNeg) {
                tempBtnMoveNeg.PreviewMouseLeftButtonDown += (sender, evt) => {
                    this.mfComMotor?.DoMoving(true);
                };
                tempBtnMoveNeg.PreviewMouseLeftButtonUp += (sender, evt) => {
                    this.mfComMotor?.Stop();
                };
            }

            if (this.GetTemplateChild("xNameButtonReset") is Button tempBtnReset) {
                tempBtnReset.PreviewMouseLeftButtonUp += (sender, evt) => {
                    this.mfComMotor?.Reset();
                };
            }

            if (this.GetTemplateChild("xNameButtonStop") is Button tempBtnStop) {
                tempBtnStop.PreviewMouseLeftButtonUp += (sender, evt) => {
                    this.mfComMotor?.Stop();
                };
            }

        }

        protected ComMotor mfComMotor => this.mfAppComPrim as ComMotor;

        /// <summary>
        /// 1. 优先根据ComID加载组件；2. 如果加载失败，再根据 PerpDevID、PerpUnitID加载组件
        /// </summary>
        /// <returns></returns>
        protected override void Load() {
            
            base.Load();

            this.PerpDevID = this.mfComMotor!.PerpDevID;
            this.PerpUnitID = this.mfComMotor.PerpUnitID;
            this.TagName = this.mfComMotor.TagName;
            this.VelCrawl = this.mfComMotor.VelCrawl;
            this.VelReset = this.mfComMotor.VelReset;
            this.VelWork = this.mfComMotor.VelWork;
            this.TPitch = this.mfComMotor.TPitch;
            this.GearRatio = this.mfComMotor.GearRatio;
            this.StrokeBeg= this.mfComMotor.StrokeBeg;
            this.StrokeEnd= this.mfComMotor.StrokeEnd;
            this.PosIdle = this.mfComMotor.PosIdle;

            this.UpdateTarget();
            this.UpdateSource();
        }
        protected override bool Save() {
            if (!this.UpdateSource()) return false;

            this.mfComMotor.VelResetSet(this.VelReset).VelCrawlSet(this.VelCrawl).VelWorkSet(this.VelWork)
                .StrokeBegSet(this.StrokeBeg).StrokeEndSet(this.StrokeEnd).PosIdleSet(this.PosIdle).TPitchSet(this.TPitch).GearRatioSet(this.GearRatio);

            return base.Save();
        }

        protected override IEnumerable<PerpDev> LoadPerpTypeItemsSource() {
            return PerpDevRepository.GetInstance().GetAll<PerpDev>().Where(it => it.Unit<Motor>().Any());
        }
        protected override IEnumerable<PerpDevUnit> LoadUnitTypeItemsSource(PerpDev perpDev) {
            return this.mfAppComPrim.PerpDev.Unit<Motor>();
        }               

        public double VelReset {
            get { return (double)GetValue(VelResetProperty); }
            set { SetValue(VelResetProperty, value); }
        }
        public static readonly DependencyProperty VelResetProperty =
            DependencyProperty.Register("VelReset", typeof(double), typeof(PrimAxis), new PropertyMetadata(default(double), (d, e) => { }));
        public double VelWork {
            get { return (double)GetValue(VelWorkProperty); }
            set { SetValue(VelWorkProperty, value); }
        }
        public static readonly DependencyProperty VelWorkProperty =
            DependencyProperty.Register("VelWork", typeof(double), typeof(PrimAxis), new PropertyMetadata(default(double), (d, e) => { }));
        public double VelCrawl {
            get { return (double)GetValue(VelCrawlProperty); }
            set { SetValue(VelCrawlProperty, value); }
        }
        public static readonly DependencyProperty VelCrawlProperty =
            DependencyProperty.Register("VelCrawl", typeof(double), typeof(PrimAxis), new PropertyMetadata(default(double), (d, e) => { }));
        public int TPitch {
            get { return (int)GetValue(TPitchProperty); }
            set { SetValue(TPitchProperty, value); }
        }
        public static readonly DependencyProperty TPitchProperty =
            DependencyProperty.Register("TPitch", typeof(int), typeof(PrimAxis), new PropertyMetadata(default(int), (d, e) => { }));
        public int GearRatio {
            get { return (int)GetValue(GearRatioProperty); }
            set { SetValue(GearRatioProperty, value); }
        }
        public static readonly DependencyProperty GearRatioProperty =
            DependencyProperty.Register("GearRatio", typeof(int), typeof(PrimAxis), new PropertyMetadata(default(int), (d, e) => { }));

        public double StrokeBeg {
            get { return (double)GetValue(StrokeBegProperty); }
            set { SetValue(StrokeBegProperty, value); }
        }
        public static readonly DependencyProperty StrokeBegProperty =
            DependencyProperty.Register("StrokeBeg", typeof(double), typeof(PrimAxis), new PropertyMetadata(default(double), (d, e) => { }));
        public double StrokeEnd {
            get { return (double)GetValue(StrokeEndProperty); }
            set { SetValue(StrokeEndProperty, value); }
        }
        public static readonly DependencyProperty StrokeEndProperty =
            DependencyProperty.Register("StrokeEnd", typeof(double), typeof(PrimAxis), new PropertyMetadata(default(double), (d, e) => { }));
        public double PosIdle {
            get { return (double)GetValue(PosIdleProperty); }
            set { SetValue(PosIdleProperty, value); }
        }
        public static readonly DependencyProperty PosIdleProperty =
            DependencyProperty.Register("PosIdle", typeof(double), typeof(PrimAxis), new PropertyMetadata(default(double), (d, e) => { }));

        /// <summary>
        /// 轴状态是否可见
        /// </summary>
        public bool StatusVisibility {
            get { return (bool)GetValue(StatusVisibilityProperty); }
            set { SetValue(StatusVisibilityProperty, value); }
        }
        public static readonly DependencyProperty StatusVisibilityProperty =
            DependencyProperty.Register("StatusVisibility", typeof(bool), typeof(PrimAxis), new PropertyMetadata(default(bool), (d, e) => { }));
        /// <summary>
        /// 轴状态标题是否可见
        /// </summary>
        public bool StatusTileVisibility {
            get { return (bool)GetValue(StatusTileVisibilityProperty); }
            set { SetValue(StatusTileVisibilityProperty, value); }
        }
        public static readonly DependencyProperty StatusTileVisibilityProperty =
            DependencyProperty.Register("StatusTileVisibility", typeof(bool), typeof(PrimAxis), new PropertyMetadata(default(bool), (d, e) => { }));

    }

    public enum AxisType {
        /// <summary>
        /// X方向的轴
        /// </summary>
        X = 1,
        /// <summary>
        /// Y方向的轴
        /// </summary>
        Y,
        /// <summary>
        /// Z方向的轴
        /// </summary>
        Z,
        /// <summary>
        /// R方向的轴
        /// </summary>
        R,
        /// <summary>
        /// C方向的轴
        /// </summary>
        C
    }

}
